// Kony


#include "Character/EnemyCharacter.h"

#include "AbilitySystemComponent.h"
#include "AbilitySystem/BaseAbilitySystemComponent.h"
#include "AbilitySystem/BaseAbilitySystemLibrary.h"
#include "AbilitySystem/BaseAttributeSet.h"
#include "Components/CapsuleComponent.h"
#include "Components/WidgetComponent.h"
#include "Component/TargetLockComponent.h"
#include "GASC_HuanLing/GASC_HuanLing.h"
#include "UI/Widget/BaseUserWidget.h"
#include "BaseGameplayTags.h"
#include "AI/BaseAIController.h"
#include "BehaviorTree/BehaviorTree.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "GameFramework/CharacterMovementComponent.h"

//敌人角色类
AEnemyCharacter::AEnemyCharacter()
{
	GetCapsuleComponent()->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore);
	GetCapsuleComponent()->SetGenerateOverlapEvents(true);
	//设置网格组件对特定碰撞通道（ECC_Visibility）的响应方式为“阻挡”（ECR_Block） 用于鼠标移动到目标高亮显示
	GetMesh()->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
	//设置网格机碰撞不对角色进行影响
	GetMesh()->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore);
	//设置网格重叠事件 ,不能设置这个 因为角色是用胶囊体进行碰撞，如果设置这个就会冲突
	GetMesh()->SetGenerateOverlapEvents(false);

	
	//设置AbilitySystemComponent 赋予 BaseAbilitySystemComponent
	AbilitySystemComponent = CreateDefaultSubobject<UBaseAbilitySystemComponent>("AbilitySystemComponent");
	//设置可复制 用于多人服务器复制数据
	AbilitySystemComponent->SetIsReplicated(true);
	//这是怪物复制模式设置成Minimal 最小复制模式， 还有其他3种 Full Mixed Minimal 
	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);

	//这部分设置是防止怪物跟随玩家时 Yaw旋转过于生硬
	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;
	GetCharacterMovement()->bOrientRotationToMovement = true;
	
	
	//设置AttributeSet属性集 赋予 BaseAttributeSet
	AttributeSet = CreateDefaultSubobject<UBaseAttributeSet>("AttributeSet");

	//设置高亮设置
	GetMesh()->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
	GetMesh()->MarkRenderStateDirty();//立即更新自定义深度设置
	Weapon->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
	Weapon->MarkRenderStateDirty();//立即更新自定义深度设置

	
}
//服务端执行函数
void AEnemyCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);
	if (!HasAuthority()) return;
	BaseAIController = Cast<ABaseAIController>(NewController);
	//设置AI控制器 黑板组件
	BaseAIController -> GetBlackboardComponent() -> InitializeBlackboard(*BehaviorTree->BlackboardAsset);
	//运行行为树
	BaseAIController -> RunBehaviorTree(BehaviorTree);
	//设置黑板上的Key值,这个是设置怪物是否被击中
	BaseAIController -> GetBlackboardComponent() ->SetValueAsBool(FName("HitReacting"), false);
	//如果是近战为false,其他为true
	BaseAIController -> GetBlackboardComponent() ->SetValueAsBool(FName("RangedAttacker"), CharacterClass != ECharacterClass::Warrior);

	BaseWalkSpeed = 250.f; //基础移动速度
	
}

//高亮敌人
void AEnemyCharacter::HighlightActor_Implementation()
{
	GetMesh()->SetRenderCustomDepth(true);
	//设置自定义深度的数值改到初始化位置
	// GetMesh()->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
	Weapon->SetRenderCustomDepth(true);
	// Weapon->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
}
//取消高亮敌人
void AEnemyCharacter::UnHighlightActor_Implementation()
{
	GetMesh()->SetRenderCustomDepth(false);
	Weapon->SetRenderCustomDepth(false);
}
//敌人部分
void AEnemyCharacter::SetMoveToLocation_Implementation(FVector& OutDestination)
{
	//不要更改目的地
}

void AEnemyCharacter::SetCombatTarget_Implementation(AActor* InCombatTarget)
{
	CombatTarget = InCombatTarget;
}

AActor* AEnemyCharacter::GetCombatTarget_Implementation() const
{
	return CombatTarget;
}

int32 AEnemyCharacter::GetPlayerLevel_Implementation()
{
	 return Level;
}

void AEnemyCharacter::Die(const FVector& DeathImpulse)
{
	//隐藏目标锁定光圈
	ICombatInterface::Execute_HideTargetIndicator(this);
	
	//生命周期
	SetLifeSpan(LifeSpan);
	//设置黑板上的Key值,这个是设置怪物是否死亡
	if (BaseAIController) BaseAIController -> GetBlackboardComponent() ->SetValueAsBool(FName("Dead"), true);
	Super::Die(DeathImpulse);
}


void AEnemyCharacter::BeginPlay()
{
	Super::BeginPlay();
	//设置默认移速
	GetCharacterMovement()->MaxWalkSpeed = BaseWalkSpeed;
	//初始化能力演员和属性信息
	InitAbilityActorInfo();
	if (HasAuthority())
	{
		//服务端权限 初始化敌人游戏能力
		UBaseAbilitySystemLibrary::GvieStartupAbilities(this,AbilitySystemComponent,CharacterClass);
	}

	if (UBaseUserWidget* BaseUserWidget = Cast<UBaseUserWidget>(HealthBar->GetUserWidgetObject()))
	{
		BaseUserWidget->SetWidgetController(this);
	}

	if (UBaseAttributeSet* BaseAS = Cast<UBaseAttributeSet>(AttributeSet))
	{
		//设置广播更变后的当前生命值
		AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(BaseAS->GetHealthAttribute())
		.AddLambda([this](const FOnAttributeChangeData& Data)
		{
			OnHealthChanged.Broadcast(Data.NewValue);
			// OnHealthChanged.Broadcast(BaseAS->GetHealth());
		});
		//设置广播更变后的最大生命值
		AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(BaseAS->GetMaxHealthAttribute())
		.AddLambda([this,BaseAS](const FOnAttributeChangeData& Data)
		{
			// OnMaxHealthChanged.Broadcast(Data.NewValue);
			OnMaxHealthChanged.Broadcast(BaseAS->GetMaxHealth());
		});
		
		//绑定游戏能力标签广播
		AbilitySystemComponent->RegisterGameplayTagEvent(FBaseGameplayTags::Get().Effects_HitReact, EGameplayTagEventType::NewOrRemoved).AddUObject(
			this,
			&AEnemyCharacter::HitReactTagChanged
		);
		//广播初始值
		OnHealthChanged.Broadcast(BaseAS->GetHealth());
		OnMaxHealthChanged.Broadcast(BaseAS->GetMaxHealth());
		
	}
}
//怪物被攻击时回调函数
void AEnemyCharacter::HitReactTagChanged(const FGameplayTag CallbackTag, int32 NewCount)
{
	//判断如果为0则不需要受击反应
	bHitRectiong = NewCount > 0;
	//如果被攻击 移动速度设为0,没被攻击就设回默认移速
	GetCharacterMovement()->MaxWalkSpeed = bHitRectiong ? 0.f : BaseWalkSpeed;
	if (bHitRectiong)
	{
		// 临时关闭动画根运动平移，避免受击蒙太奇的RootMotion覆盖Launch方向
		SetAnimRootMotionTranslationScale(0.f);
	}
	else
	{
		SetAnimRootMotionTranslationScale(1.f);
	}
	if (BaseAIController && BaseAIController -> GetBlackboardComponent())
	{
		//设置黑板上的Key值,这个是设置怪物被击中
		BaseAIController -> GetBlackboardComponent() ->SetValueAsBool(FName("HitReacting"), bHitRectiong);
	}
	
}

void AEnemyCharacter::InitAbilityActorInfo()
{
	//初始化怪物能力系统， InitAbilityActorInfo 初始化演员能力信息函数
	AbilitySystemComponent->InitAbilityActorInfo(this, this);
	//通知能力系统基类，怪物角色信息已经初始化完毕
	Cast<UBaseAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();
	//注册游戏标签事件 - 眩晕,绑定到玩家角色类中的处理更变函数
	AbilitySystemComponent->RegisterGameplayTagEvent(FBaseGameplayTags::Get().Debuff_Propertie_Stun, EGameplayTagEventType::Type::NewOrRemoved)
	.AddUObject(this, &AEnemyCharacter::StunTagChanged);
	//击倒
	AbilitySystemComponent->RegisterGameplayTagEvent(FBaseGameplayTags::Get().Debuff_Propertie_Down, EGameplayTagEventType::Type::NewOrRemoved)
	.AddUObject(this, &AEnemyCharacter::DownTagChanged);
	if (HasAuthority())
	{
		//服务端权限 初始化 敌人 主属性默认值 和 次要属性默认值 
		InitializeDefaultAttributes();
	}
	//广播这里存在的ASC能力系统组件，用于不如粒子系统组件 无法直接获取ASC 通过这样广播即可获取到
	OnAscRegistered.Broadcast(AbilitySystemComponent);
}

void AEnemyCharacter::InitializeDefaultAttributes() const
{
	//初始化 通过敌人类别传入角色的等级信息等绑定到能力组件
	UBaseAbilitySystemLibrary::InitializeDefaultAttributes(this,CharacterClass,Level,AbilitySystemComponent);
}
//重写眩晕标签更变函数
void AEnemyCharacter::StunTagChanged(const FGameplayTag CallbackTag, int32 NewCount)
{
	Super::StunTagChanged(CallbackTag, NewCount);
	if (BaseAIController && BaseAIController -> GetBlackboardComponent())
	{
		//设置黑板上的Key值,这个是设置怪物被击中
		BaseAIController -> GetBlackboardComponent() ->SetValueAsBool(FName("Stunned"), bIsStunned);
	}
}
//重写击倒标签更变函数
void AEnemyCharacter::DownTagChanged(const FGameplayTag CallbackTag, int32 NewCount)
{
	Super::DownTagChanged(CallbackTag, NewCount);
	if (BaseAIController && BaseAIController -> GetBlackboardComponent())
	{
		//设置黑板上的Key值,这个是设置怪物被击中
		BaseAIController -> GetBlackboardComponent() ->SetValueAsBool(FName("Downed"), bIsDown);
	}
}
